package com.ysjy.course.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wkbb.common.base.BaseServiceImpl;
import com.wkbb.common.constants.ErrorCode;
import com.wkbb.common.constants.PromptMessage;
import com.wkbb.common.dto.ResultDTO;
import com.wkbb.common.dto.basic.ClassInfo;
import com.wkbb.common.dto.basic.StudentInfoDto;
import com.wkbb.common.dto.basic.UserDto;
import com.wkbb.common.dto.course.CourseClassDto;
import com.wkbb.common.dto.course.CourseTimeDto;
import com.wkbb.common.handler.JsonUtil;
import com.wkbb.common.utils.DateUtil;
import com.wkbb.common.utils.RandomUtil;
import com.wkbb.sports.mapper.BasicMapper;
import com.ysjy.course.dto.AttendDto;
import com.ysjy.course.dto.CourseAttendDto;
import com.ysjy.course.dto.SignUpUserDto;
import com.ysjy.course.dto.TeacherCourseTimeFeedbackDto;
import com.ysjy.course.mapper.*;
import com.ysjy.course.model.*;
import com.ysjy.course.service.CourseClassService;
import com.ysjy.course.utils.BeanBind;
import com.ysjy.feign.BasicFeignService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.util.*;

@Service
@Slf4j
public class CourseClassServiceImpl extends BaseServiceImpl<CourseClassDto> implements CourseClassService {

    @Autowired
    private BasicFeignService basicFeignService;
    @Autowired
    private CourseClassMapper courseClassMapper;
    @Autowired
    private SignUpUserMapper signUpUserMapper;
    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private TrusteeshipMapper trusteeshipMapper;
    @Autowired
    private YsTeacherMapper teacherMapper;
    @Autowired
    private AttendMapper attendMapper;
    @Autowired
    private BasicMapper basicMapper;

    @Autowired
    public void setMapper(CourseClassMapper mapper) {
        super.setMapper(mapper);
    }

    @Override
    public ResultDTO<Boolean> generateCourseTime(String serviceUniqueId, Integer classType, Long classId) {
        List<CourseTime> courseTimeList = null;
        //4课程班 5托管班
        if (classType == 4 ){
            OrgCourse orgCourse = courseMapper.getOrgCourseByUniqueId(serviceUniqueId, null);
            if (orgCourse == null){
                return ResultDTO.errorResult(PromptMessage.COURSE_IS_NULL);
            }
            if (orgCourse.getClassTime() == null || orgCourse.getStartTime() == null || orgCourse.getTeacherId() == null || orgCourse.getSiteId() == null){
                return ResultDTO.errorResult("请先填写上课时间、开课时间、教师、场地等信息");
            }

            //排课时
            String classTime = orgCourse.getClassTime();
            String[] arr = classTime.split(",");
            List<Integer> weekDays = new ArrayList<>();
            String timeStr = null;
            String startTime = null;
            String endTime = null;

            String[] ts = classTime.split(",");
            String[] timeDays = ts[0].split(" ");
            if (timeDays.length == 2){
                String[] times = timeDays[1].split("~");
                if (times.length == 2){
                    startTime = times[0];
                    endTime = times[1];
                }
            }
            if (startTime != null && endTime != null){
                for (String weekDay : arr) {
                    timeDays = weekDay.split(" ");
                    if (timeDays.length == 2){
                        int weekday = DateUtil.getWeekNum(timeDays[0]);
                        if (null == timeStr){
                            timeStr = timeDays[1];
                        }
                        weekDays.add(weekday);
                    }
                }
                try {
                    List<String> times = DateUtil.getDayOfWeekWithinDateInterva2(DateUtil.dateSDF.format(orgCourse.getStartTime()),null, orgCourse.getTimeNum(), weekDays);
                    courseTimeList = courseMapper.getCourseTimeListByUniqueId(orgCourse.getUniqueId());
                    if (courseTimeList.size() == times.size()){
                        for (int i=0 ; i<times.size() ; i++){
                            CourseTime courseTime = courseTimeList.get(i);
                            String time = times.get(i);

                            String startDate = time + " " + startTime;
                            String endDate = time + " " + endTime;

                            courseTime.setStartTime(DateUtil.dateMinSDF.parse(startDate));
                            courseTime.setEndTime(DateUtil.dateMinSDF.parse(endDate));
                        }
                    }
                    courseMapper.delCourseTimes(orgCourse.getUniqueId());
                } catch (ParseException e) {
                    throw new RuntimeException(e);
                }
            }
        }else{
            YsTrusteeship trusteeship = trusteeshipMapper.getTrusteeshipByUniqueId(serviceUniqueId,null);
            if (trusteeship == null){
                return ResultDTO.errorResult(PromptMessage.TRUSTEESHIP_IS_NULL);
            }
            //排课时
            String classTime = trusteeship.getClassTime();
            String[] arr = classTime.split(",");
            List<Integer> weekDays = new ArrayList<>();
            String timeStr = null;
            String startTime = null;
            String endTime = null;

            String[] ts = classTime.split(",");
            String[] timeDays = ts[0].split(" ");
            if (timeDays.length == 2){
                String[] times = timeDays[1].split("~");
                if (times.length == 2){
                    startTime = times[0];
                    endTime = times[1];
                }
            }
            if (startTime != null && endTime != null){
                for (String weekDay : arr) {
                    timeDays = weekDay.split(" ");
                    if (timeDays.length == 2){
                        int weekday = DateUtil.getWeekNum(timeDays[0]);
                        if (null == timeStr){
                            timeStr = timeDays[1];
                        }
                        weekDays.add(weekday);
                    }
                }
                try {
                    List<String> times = DateUtil.getDayOfWeekWithinDateInterva2(DateUtil.dateSDF.format(trusteeship.getStartTime()),DateUtil.dateSDF.format(trusteeship.getEndTime()), 0, weekDays);
//                    log.info("times:{}",JsonUtil.objectToJson(times));
                    Date currDate = new Date();
                    courseTimeList = new ArrayList<>();
                    for (int i=0 ; i<times.size() ; i++){
                        CourseTime courseTime = new CourseTime();
                        courseTime.setCourseUniqueId(trusteeship.getUniqueId());
                        courseTime.setTitle(trusteeship.getTitle());
                        courseTime.setSiteId(trusteeship.getSiteId());
                        courseTime.setTeacherId(trusteeship.getTeacherId());
                        courseTime.setCreateTime(currDate);
                        String time = times.get(i);

                        String startDate = time + " " + startTime;
                        String endDate = time + " " + endTime;

                        courseTime.setStartTime(DateUtil.dateMinSDF.parse(startDate));
                        courseTime.setEndTime(DateUtil.dateMinSDF.parse(endDate));
                        courseTimeList.add(courseTime);
                    }
                } catch (ParseException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        if (courseTimeList != null && !courseTimeList.isEmpty()){
            for (int i=0 ; i<courseTimeList.size() ; i++){
                CourseTime courseTime = courseTimeList.get(i);
                courseTime.setCourseClassId(classId);
            }
            log.info("courseTimeList:"+JsonUtil.objectToJson(courseTimeList));
            courseMapper.insertCourseTimeBatch(courseTimeList);
        }
        return new ResultDTO<>();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDTO<Boolean> putCourseClass(CourseClassDto data) throws Exception {
        if (data.getId() == null){
            //查找是否有重复名称的班级
            Map<String, Object> params1 = new HashMap<>();
            params1.put("orgId",data.getOrgId());
            params1.put("className",data.getClassName());
            CourseClassDto classDto1 = courseClassMapper.getByMapParams(params1);
            if (classDto1 != null){
                return ResultDTO.errorResult("课班名称重复，无法提交");
            }

            Map<String, Object> params = new HashMap<>();
            params.put("classType",data.getClassType());
            params.put("serviceUniqueId",data.getServiceUniqueId());
            CourseClassDto classDto = courseClassMapper.getByMapParams(params);
            if (classDto != null){
                return ResultDTO.errorResult("当前课程已开班，请勿重复操作");
            }
            List<CourseTime> courseTimeList = null;
            //4课程班 5托管班
            if (data.getClassType() == 4){
                OrgCourse orgCourse = courseMapper.getOrgCourseByUniqueId(data.getServiceUniqueId(), null);
                if (orgCourse == null){
                    return ResultDTO.errorResult(PromptMessage.COURSE_IS_NULL);
                }
                if (orgCourse.getShelvesStatus() == null || orgCourse.getShelvesStatus() == 0){
                    return ResultDTO.errorResult("未上架服务，无法开班");
                }
                if (orgCourse.getClassTime() == null || orgCourse.getStartTime() == null || orgCourse.getTeacherId() == null || orgCourse.getSiteId() == null){
                    return ResultDTO.errorResult("请先填写上课时间、开课时间、教师、场地等信息");
                }
                data.setLogo(orgCourse.getLogo());
                data.setServiceType(orgCourse.getType());
                data.setAmount(orgCourse.getAmount());
                data.setServiceName(orgCourse.getTitle());
                data.setTeacherId(orgCourse.getTeacherId());
                data.setSiteId(orgCourse.getSiteId());
                data.setTagId(orgCourse.getTagId());
                data.setGradeIds(orgCourse.getGradeIds());
                data.setGradeNames(orgCourse.getGradeNames());
                data.setMaxTimeNum(orgCourse.getTimeNum());
                data.setMaxSignUpNum(orgCourse.getMaxSignUpNum());
                data.setClassTime(orgCourse.getClassTime());
                data.setSignUpStartTime(orgCourse.getSignUpStartTime());
                data.setSignUpEndTime(orgCourse.getSignUpEndTime());
                data.setStartTime(orgCourse.getStartTime());
                data.setEndTime(orgCourse.getEndTime());
                data.setServiceYear(orgCourse.getSchoolYear());

                //排课时
                String classTime = orgCourse.getClassTime();
                String[] arr = classTime.split(",");
                List<Integer> weekDays = new ArrayList<>();
                String timeStr = null;
                String startTime = null;
                String endTime = null;

                String[] ts = classTime.split(",");
                String[] timeDays = ts[0].split(" ");
                if (timeDays.length == 2){
                    String[] times = timeDays[1].split("~");
                    if (times.length == 2){
                        startTime = times[0];
                        endTime = times[1];
                    }
                }
                if (startTime != null && endTime != null){
                    for (String weekDay : arr) {
                        timeDays = weekDay.split(" ");
                        if (timeDays.length == 2){
                            int weekday = DateUtil.getWeekNum(timeDays[0]);
                            if (null == timeStr){
                                timeStr = timeDays[1];
                            }
                            weekDays.add(weekday);
                        }
                    }
                    try {
                        List<String> times = DateUtil.getDayOfWeekWithinDateInterva2(DateUtil.dateSDF.format(orgCourse.getStartTime()),null, orgCourse.getTimeNum(), weekDays);
                        courseTimeList = courseMapper.getCourseTimeListByUniqueId(orgCourse.getUniqueId());
                        if (courseTimeList.size() == times.size()){
                            for (int i=0 ; i<times.size() ; i++){
                                CourseTime courseTime = courseTimeList.get(i);
                                String time = times.get(i);

                                String startDate = time + " " + startTime;
                                String endDate = time + " " + endTime;

                                courseTime.setStartTime(DateUtil.dateMinSDF.parse(startDate));
                                courseTime.setEndTime(DateUtil.dateMinSDF.parse(endDate));
                            }
                        }
                        courseMapper.delCourseTimes(orgCourse.getUniqueId());
                    } catch (ParseException e) {
                        throw new RuntimeException(e);
                    }
                }
            }else{
                YsTrusteeship trusteeship = trusteeshipMapper.getTrusteeshipByUniqueId(data.getServiceUniqueId(),null);
                if (trusteeship == null){
                    return ResultDTO.errorResult(PromptMessage.TRUSTEESHIP_IS_NULL);
                }
                if (trusteeship.getShelvesStatus() == null || trusteeship.getShelvesStatus() == 0){
                    return ResultDTO.errorResult("未上架服务，无法开班");
                }
                data.setLogo(trusteeship.getLogo());
                data.setAmount(trusteeship.getAmount());
                data.setServiceType(trusteeship.getType());
                data.setServiceName(trusteeship.getTitle());
                data.setTeacherId(trusteeship.getTeacherId());
                data.setSiteId(trusteeship.getSiteId());
                data.setTagId(trusteeship.getTagId());
                data.setGradeIds(trusteeship.getGradeIds());
                data.setGradeNames(trusteeship.getGradeNames());
                data.setClassTime(trusteeship.getClassTime());
                data.setSignUpStartTime(trusteeship.getSignUpStartTime());
                data.setMaxSignUpNum(trusteeship.getMaxSignUpNum());
                data.setSignUpEndTime(trusteeship.getSignUpEndTime());
                data.setStartTime(trusteeship.getStartTime());
                data.setEndTime(trusteeship.getEndTime());
                data.setServiceYear(trusteeship.getServiceYear());

                //排课时
                String classTime = trusteeship.getClassTime();
                String[] arr = classTime.split(",");
                List<Integer> weekDays = new ArrayList<>();
                String timeStr = null;
                String startTime = null;
                String endTime = null;

                String[] ts = classTime.split(",");
                String[] timeDays = ts[0].split(" ");
                if (timeDays.length == 2){
                    String[] times = timeDays[1].split("~");
                    if (times.length == 2){
                        startTime = times[0];
                        endTime = times[1];
                    }
                }
                if (startTime != null && endTime != null){
                    for (String weekDay : arr) {
                        timeDays = weekDay.split(" ");
                        if (timeDays.length == 2){
                            int weekday = DateUtil.getWeekNum(timeDays[0]);
                            if (null == timeStr){
                                timeStr = timeDays[1];
                            }
                            weekDays.add(weekday);
                        }
                    }
                    try {
                        List<String> times = DateUtil.getDayOfWeekWithinDateInterva2(DateUtil.dateSDF.format(trusteeship.getStartTime()),DateUtil.dateSDF.format(trusteeship.getEndTime()), 0, weekDays);
                        Date currDate = new Date();
                        courseTimeList = new ArrayList<>();
                        for (int i=0 ; i<times.size() ; i++){
                            CourseTime courseTime = new CourseTime();
                            courseTime.setCourseUniqueId(trusteeship.getUniqueId());
                            courseTime.setTitle(trusteeship.getTitle());
                            courseTime.setSiteId(trusteeship.getSiteId());
                            courseTime.setTeacherId(trusteeship.getTeacherId());
                            courseTime.setCreateTime(currDate);
                            String time = times.get(i);

                            String startDate = time + " " + startTime;
                            String endDate = time + " " + endTime;

                            courseTime.setStartTime(DateUtil.dateMinSDF.parse(startDate));
                            courseTime.setEndTime(DateUtil.dateMinSDF.parse(endDate));
                            courseTimeList.add(courseTime);
                        }
                    } catch (ParseException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
            ClassInfo classInfo = new ClassInfo();
            classInfo.setMasterId(data.getTeacherId());

            classInfo.setGradeId(40L);
            classInfo.setGradeName("一年级");
            classInfo.setClassType(data.getClassType());
            classInfo.setOrgId(data.getOrgId());
            classInfo.setOrgName(data.getOrgName());
            classInfo.setServiceUniqueId(data.getServiceUniqueId());
            classInfo.setServiceName(data.getServiceName());
            classInfo.setCreateBy(data.getCreateBy());
            classInfo.setInviteCode(RandomUtil.generateString(8));
            classInfo.setClassName(data.getClassName());
            YsTeacher ysTeacher = teacherMapper.getByPrimaryKey(data.getTeacherId());
            if (ysTeacher != null){
                classInfo.setMasterName(ysTeacher.getRealName());
                classInfo.setMasterPhone(ysTeacher.getMobile());
            }

            int insertClassInfo = courseClassMapper.insertClassInfo(classInfo);
            if (insertClassInfo > 0){
                data.setClassId(classInfo.getId());
                courseClassMapper.insert(data);

                if (courseTimeList != null && !courseTimeList.isEmpty()){
                    for (int i=0 ; i<courseTimeList.size() ; i++){
                        CourseTime courseTime = courseTimeList.get(i);
                        courseTime.setCourseClassId(classInfo.getId());
                    }
                    log.info("courseTimeList:"+JsonUtil.objectToJson(courseTimeList));
                    courseMapper.insertCourseTimeBatch(courseTimeList);
                }

                //查找已报名学生，入班
                List<Long> stuList = signUpUserMapper.getStudentList(data.getServiceUniqueId());
                if (stuList.size() > 0){
                    StringBuilder sb = new StringBuilder();
                    for (Long i:stuList){
                        sb.append(i).append(",");
                    }
                    sb.deleteCharAt(sb.length()-1);
                    return basicFeignService.joinClassByStudentsBack(sb.toString(),data.getClassId());
                }else return new ResultDTO<>();
            }else {
                return new ResultDTO<>(ErrorCode.SYSTEM_ERROR);
            }
        }else{
            CourseClassDto classDto = courseClassMapper.getByPrimaryKey(data.getId());
            if (classDto == null){
                return new ResultDTO<>(ErrorCode.SYSTEM_ERROR);
            }
            //查找是否有重复名称的班级
            Map<String, Object> params1 = new HashMap<>();
            params1.put("orgId",data.getOrgId());
            params1.put("className",data.getClassName());
            CourseClassDto classDto1 = courseClassMapper.getByMapParams(params1);
            if (classDto1 != null && !Objects.equals(classDto1.getId(), data.getId())){
                return ResultDTO.errorResult("课班名称重复，无法提交");
            }
            classDto.setClassName(data.getClassName());
            courseClassMapper.update(classDto);
            return new ResultDTO<>();
        }
    }

    @Override
    @Transactional(readOnly = true)
    public List<CourseClassDto> getCourseClassListByStudent(Map<String, Object> params) {
        return courseClassMapper.getCourseClassListByStudent(params);
    }

    @Override
    public void joinClassBySignUpUser(SignUpUser signUpUser) {
        Map<String, Object> params = new HashMap<>();
        int classType = signUpUser.getSignUpType()+3;
        params.put("classType",classType);
        params.put("serviceUniqueId",signUpUser.getGoodNumber());
        CourseClassDto classDto = courseClassMapper.getByMapParams(params);
        if (classDto != null){
            basicFeignService.joinClassByStudentsBack(signUpUser.getStudentId().toString(), classDto.getClassId());
        }
    }

    @Override
    public ResultDTO<Boolean> applyChangeClass(Long signUpUserId, Long newClassId, String way) {
        SignUpUser signUpUser = signUpUserMapper.getByPrimaryKey(signUpUserId);
        if (signUpUser == null){
            return ResultDTO.errorResult("不存在的报名ID");
        }
        Map<String, Object> params = new HashMap<>();
        int classType = signUpUser.getSignUpType()+3;
        params.put("classType",classType);
        params.put("serviceUniqueId",signUpUser.getGoodNumber());
        CourseClassDto oldClass = courseClassMapper.getByMapParams(params);
        if (oldClass == null){
            return ResultDTO.errorResult("班级尚未创建，无法调班");
        }
        oldClass.initStatus();
        if (oldClass.getStatus() == 4){
            return ResultDTO.errorResult("班级已结课，无法调班");
        }
        Map<String, Object> params1 = new HashMap<>();
        params1.put("classId",newClassId);
        CourseClassDto newClass = courseClassMapper.getByMapParams(params1);
        if (newClass == null){
            return ResultDTO.errorResult("班级尚未创建，无法调班");
        }
        if (newClass.getSignUpNum() >= newClass.getMaxSignUpNum()){
            return ResultDTO.errorResult("班级人数已满，无法调班");
        }
        newClass.initStatus();
        if (newClass.getStatus() == 4){
            return ResultDTO.errorResult("班级已结课，无法调班");
        }
        if (!Objects.equals(oldClass.getOrgId(), newClass.getOrgId())){
            return ResultDTO.errorResult("不是同一个学校，无法调班");
        }

        //插入申请表
        ClassChangeApply data = new ClassChangeApply();
        data.setSignUpId(signUpUserId);
        data.setOldServiceUniqueId(oldClass.getServiceUniqueId());
        data.setOrderNumber(signUpUser.getOrderNumber());
        data.setOldClassId(oldClass.getClassId());
        data.setNewClassId(newClass.getClassId());
        data.setWay(way);
        data.setOrgId(oldClass.getOrgId());
        courseClassMapper.insertClassChangeApply(data);
        return new ResultDTO<>();
    }

    @Override
    public PageInfo<ClassChangeApply> getChangeClassApplyListByPage(Map<String, Object> params, int pageNo, int pageSize) {
        Page<ClassChangeApply> page = PageHelper.startPage(pageNo, pageSize,true);
        PageInfo<ClassChangeApply> pageInfo = new PageInfo<>(courseClassMapper.getChangeClassApplyListByPage(params));
        pageInfo.setTotal(page.getTotal());
        return pageInfo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDTO<Boolean> auditChangeClass(Long id, Integer state,UserDto userDto) {
        ClassChangeApply classChangeApply = courseClassMapper.findChangeClassApplyById(id);
        if (classChangeApply == null){
            return ResultDTO.errorResult("不存在的申请ID");
        }
        if (state == 1){
            classChangeApply.setState(state);
            SignUpUser signUpUser = signUpUserMapper.getByPrimaryKey(classChangeApply.getSignUpId());
            if (signUpUser == null){
                return ResultDTO.errorResult("不存在的报名ID");
            }
            Map<String, Object> params = new HashMap<>();
            int classType = signUpUser.getSignUpType()+3;
            params.put("classType",classType);
            params.put("serviceUniqueId",signUpUser.getGoodNumber());
            CourseClassDto oldClass = courseClassMapper.getByMapParams(params);
            oldClass.initStatus();
            if (oldClass.getStatus() == 4){
                return ResultDTO.errorResult("班级已结课，无法调班");
            }

            Map<String, Object> params1 = new HashMap<>();
            params1.put("classId",classChangeApply.getOldClassId());
            CourseClassDto newClass = courseClassMapper.getByMapParams(params1);
            if (newClass.getSignUpNum() >= newClass.getMaxSignUpNum()){
                return ResultDTO.errorResult("班级人数已满，无法调班");
            }
            newClass.initStatus();
            if (newClass.getStatus() == 4){
                return ResultDTO.errorResult("班级已结课，无法调班");
            }
            //更新报名表
            signUpUser.setGoodNumber(newClass.getServiceUniqueId());
            signUpUser.setSignUpType(newClass.getClassType() - 3);
            signUpUserMapper.update(signUpUser);

            ClassChangeLog classChangeLog = new ClassChangeLog();
            classChangeLog.setSignUpId(classChangeApply.getSignUpId());
            classChangeLog.setOldServiceUniqueId(oldClass.getServiceUniqueId());
            classChangeLog.setOrderNumber(signUpUser.getOrderNumber());
            classChangeLog.setWay(classChangeApply.getWay());
            classChangeLog.setOldClassId(oldClass.getClassId());
            classChangeLog.setNewClassId(newClass.getClassId());
            classChangeLog.setOperationUserId(userDto.getId());
            classChangeLog.setOperationUserName(userDto.getName());
            courseClassMapper.insertClassChangeLog(classChangeLog);

            //切换班级
            basicFeignService.exitClassByStudentsBack(signUpUser.getStudentId().toString(), oldClass.getClassId());
            basicFeignService.joinClassByStudentsBack(signUpUser.getStudentId().toString(), newClass.getClassId());

            courseClassMapper.updateClassChangeApply(classChangeApply);
            return new ResultDTO<>();
        }else if (state == 2){
            classChangeApply.setState(state);
            courseClassMapper.updateClassChangeApply(classChangeApply);
            return new ResultDTO<>();
        }
        return ResultDTO.errorResult("state参数错误");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDTO<Boolean> stuChangeClass(Long signUpUserId, Long newClassId,String way, UserDto userDto) throws Exception {
        SignUpUser signUpUser = signUpUserMapper.getByPrimaryKey(signUpUserId);
        if (signUpUser == null){
            return ResultDTO.errorResult("不存在的报名ID");
        }
        Map<String, Object> params = new HashMap<>();
        int classType = signUpUser.getSignUpType()+3;
        params.put("classType",classType);
        params.put("serviceUniqueId",signUpUser.getGoodNumber());
        CourseClassDto oldClass = courseClassMapper.getByMapParams(params);
        if (oldClass == null){
            return ResultDTO.errorResult("班级尚未创建，无法调班");
        }
        oldClass.initStatus();
        if (oldClass.getStatus() == 4){
            return ResultDTO.errorResult("班级已结课，无法调班");
        }
        Map<String, Object> params1 = new HashMap<>();
        params1.put("classId",newClassId);
        CourseClassDto newClass = courseClassMapper.getByMapParams(params1);
        if (newClass == null){
            return ResultDTO.errorResult("班级尚未创建，无法调班");
        }
        if (newClass.getSignUpNum() >= newClass.getMaxSignUpNum()){
            return ResultDTO.errorResult("班级人数已满，无法调班");
        }
        newClass.initStatus();
        if (newClass.getStatus() == 4){
            return ResultDTO.errorResult("班级已结课，无法调班");
        }
        if (!Objects.equals(oldClass.getOrgId(), newClass.getOrgId())){
            return ResultDTO.errorResult("不是同一个学校，无法调班");
        }

        //更新报名表
        signUpUser.setGoodNumber(newClass.getServiceUniqueId());
        signUpUser.setSignUpType(newClass.getClassType() - 3);
        signUpUserMapper.update(signUpUser);

        ClassChangeLog classChangeLog = new ClassChangeLog();
        classChangeLog.setSignUpId(signUpUserId);
        classChangeLog.setOldServiceUniqueId(oldClass.getServiceUniqueId());
        classChangeLog.setOrderNumber(signUpUser.getOrderNumber());
        classChangeLog.setWay(way);
        classChangeLog.setOldClassId(oldClass.getClassId());
        classChangeLog.setNewClassId(newClass.getClassId());
        classChangeLog.setOperationUserId(userDto.getId());
        classChangeLog.setOperationUserName(userDto.getName());
        courseClassMapper.insertClassChangeLog(classChangeLog);

        //切换班级
        basicFeignService.exitClassByStudentsBack(signUpUser.getStudentId().toString(), oldClass.getClassId());
        basicFeignService.joinClassByStudentsBack(signUpUser.getStudentId().toString(), newClass.getClassId());
        return new ResultDTO<>();
    }

    @Override
    @Transactional(readOnly = true)
    public List<CourseTimeDto> getCourseTimeList(Map<String, Object> params) {
        return courseClassMapper.getCourseTimeList(params);
    }

    @Override
    @Transactional(readOnly = true)
    public List<String> getHaveClassByMonth(Map<String, Object> params) {
        return courseClassMapper.getHaveClassByMonth(params);
    }

    @Override
    @Transactional(readOnly = true)
    public Map<String, Object> getCourseTimeCountByMonth(Map<String, Object> params) {
        return courseClassMapper.getCourseTimeCountByMonth(params);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDTO<Boolean> putCourseTimeLeave(CourseAttendLeave data) throws Exception {
        Map<String, Object> map = new HashMap<>();
        map.put("courseTimeId",data.getCourseTimeId());
        map.put("studentId",data.getStudentId());
        List<CourseAttendLeave> list = attendMapper.findAttendLeaveList(map);
        if (!list.isEmpty()) return ResultDTO.errorResult("当前课时已请过假，请勿重复操作");
        attendMapper.insertAttendLeave(data);
        CourseAttend courseAttend = new CourseAttend();
        courseAttend.setCourseTimeId(data.getCourseTimeId());
        courseAttend.setAttenStatus(3);
        courseAttend.setStudentId(data.getStudentId());
        attendMapper.insert(courseAttend);
        return new ResultDTO<>(true);
    }

    @Override
    public ResultDTO<Boolean> putCourseTimeFeedback(CourseTimeFeedback data) throws Exception {
        Map<String, Object> map = new HashMap<>();
        map.put("courseTimeId",data.getCourseTimeId());
        map.put("studentId",data.getStudentId());
        List<CourseTimeFeedback> list = attendMapper.findCourseFeedTimebackList(map);
        if (!list.isEmpty()) return ResultDTO.errorResult("当前课时已经反馈过，请勿重复操作");
        attendMapper.insertCourseTimeFeedback(data);
        return new ResultDTO<>();
    }

    @Override
    public ResultDTO<Boolean> putCourseFeedback(CourseFeedback data) throws Exception {
        Map<String, Object> map = new HashMap<>();
        map.put("serviceUniqueId",data.getServiceUniqueId());
        map.put("studentId",data.getStudentId());
        List<CourseFeedback> list = attendMapper.findCourseFeedbackList(map);
        if (!list.isEmpty()) return ResultDTO.errorResult("当前课程已经反馈过，请勿重复操作");
        attendMapper.insertCourseFeedback(data);
        return new ResultDTO<>();
    }

    @Override
    @Transactional(readOnly = true)
    public PageInfo<SignUpUserDto> getCourseClassStudentListByPage(Map<String, Object> params, int pageNo, int pageSize) {
        Page<SignUpUserDto> page = PageHelper.startPage(pageNo, pageSize,true);
        PageInfo<SignUpUserDto> pageInfo = new PageInfo<>(signUpUserMapper.getCourseClassStudentList(params));
        pageInfo.setTotal(page.getTotal());
        return pageInfo;
    }

    @Override
    @Transactional(readOnly = true)
    public List<CourseClassDto> getCourseClassListByTeacher(Map<String, Object> params) {
        return courseClassMapper.getCourseClassListByTeacher(params);
    }

    @Override
    @Transactional(readOnly = true)
    public List<CourseAttendDto> getCourseTimeAttendStuList(Map<String, Object> params) {
        return attendMapper.getCourseTimeAttendStuList(params);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDTO<Boolean> putCourseTimeAttend(List<CourseAttendDto> dtos) throws Exception{
        attendMapper.clearAttendByCourseTimeId(dtos.get(0).getCourseTimeId());
        List<CourseAttend> list = new ArrayList<>();
        BeanBind bind = new BeanBind(CourseAttendDto.class,CourseAttend.class);
        Date currDate = new Date();
        for (CourseAttendDto dto:dtos){
            if (dto.getAttenStatus() < 3){
                CourseAttend data = (CourseAttend) bind.bindBean(dto);
                data.setCreateTime(currDate);
                list.add(data);
            }
        }
        attendMapper.insertBatch(list);
        return new ResultDTO<>();
    }

    @Override
    @Transactional(readOnly = true)
    public ResultDTO<CourseClassDto> getCourseClass(Integer classId) {
        CourseClassDto dto = courseClassMapper.getCourseClassByClassId(classId);
        if (dto == null) return ResultDTO.errorResult("不存在的课班ID");
        dto.initStatus();
        Map<String, Object> params = new HashMap<>();
        params.put("serviceUniqueId", dto.getServiceUniqueId());
        List<CourseTimeDto> courseTimeList = courseClassMapper.getCourseTimeList(params);
        dto.setCourseTimeList(courseTimeList);
        return new ResultDTO<>(dto);
    }

    @Override
    public ResultDTO<Boolean> putMessage(YsMessage data) throws Exception{
        courseClassMapper.insertMessage(data);
        return new ResultDTO<>();
    }

    @Override
    public ResultDTO<Boolean> putTeacherCourseTimeFeedback(TeacherCourseTimeFeedback data) throws Exception{
        courseClassMapper.insertTeacherCourseTimeFeedback(data);
        return new ResultDTO<>();
    }

    @Override
    public ResultDTO<Boolean> likeTeacherCourseTimeFeedback(TeacherCourseTimeFeedbackLike data) throws Exception{

        Map<String, Object> map = new HashMap<>();
        map.put("feedbackId",data.getFeedbackId());
        map.put("studentId",data.getStudentId());
        List<TeacherCourseTimeFeedbackLike> list = courseClassMapper.getLikeListByMapParams(map);
        if (!list.isEmpty()) return ResultDTO.errorResult("已经点赞过，请勿重复操作");

        StudentInfoDto stu = basicMapper.getStudentInfoByStudentId(data.getStudentId());
        if (stu == null){
            return ResultDTO.errorResult("错误！学生ID异常");
        }
        data.setStudentAvatar(stu.getHeadImgUrl());
        data.setStudentName(stu.getName());
        courseClassMapper.insertTeacherCourseTimeFeedbackLike(data);
        return new ResultDTO<>();
    }

    @Override
    public ResultDTO<Boolean> commentTeacherCourseTimeFeedback(TeacherCourseTimeFeedbackLike data) throws Exception{
        StudentInfoDto stu = basicMapper.getStudentInfoByStudentId(data.getStudentId());
        if (stu == null){
            return ResultDTO.errorResult("错误！学生ID异常");
        }
        data.setStudentAvatar(stu.getHeadImgUrl());
        data.setStudentName(stu.getName());
        courseClassMapper.insertTeacherCourseTimeFeedbackComment(data);
        return new ResultDTO<>();
    }

    @Override
    @Transactional(readOnly = true)
    public PageInfo<TeacherCourseTimeFeedbackDto> getTeacherCourseTimeFeedbackListByStudent(Map<String, Object> params, int pageNo, int pageSize) {
        Page<TeacherCourseTimeFeedbackDto> page = PageHelper.startPage(pageNo, pageSize,true);
        PageInfo<TeacherCourseTimeFeedbackDto> pageInfo = new PageInfo<>(courseClassMapper.getTeacherCourseTimeFeedbackListByStudent(params));
        pageInfo.setTotal(page.getTotal());
        return pageInfo;
    }

    @Override
    @Transactional(readOnly = true)
    public PageInfo<TeacherCourseTimeFeedbackDto> getTeacherCourseTimeFeedbackListByPage(Map<String, Object> params, int pageNo, int pageSize) {
        Page<TeacherCourseTimeFeedbackDto> page = PageHelper.startPage(pageNo, pageSize,true);
        PageInfo<TeacherCourseTimeFeedbackDto> pageInfo = new PageInfo<>(courseClassMapper.getTeacherCourseTimeFeedbackListByPage(params));
        pageInfo.setTotal(page.getTotal());
        return pageInfo;
    }

    @Override
    @Transactional(readOnly = true)
    public PageInfo<AttendDto> getCourseTimeAttendListByPage(Map<String, Object> params, int pageNo, int pageSize) {
        Page<AttendDto> page = PageHelper.startPage(pageNo, pageSize,true);
        PageInfo<AttendDto> pageInfo = new PageInfo<>(attendMapper.getCourseTimeAttendListByPage(params));
        pageInfo.setTotal(page.getTotal());
        return pageInfo;
    }

    @Override
    @Transactional(readOnly = true)
    public PageInfo<YsMessage> getMessageListByPage(Map<String, Object> params, int pageNo, int pageSize) {
        Page<YsMessage> page = PageHelper.startPage(pageNo, pageSize,true);
        PageInfo<YsMessage> pageInfo = new PageInfo<>(courseClassMapper.getMessageListByPage(params));
        pageInfo.setTotal(page.getTotal());
        return pageInfo;
    }

    @Override
    @Transactional(readOnly = true)
    public Map<String, Object> getMessageCount(Map<String, Object> params) {
        return courseClassMapper.getMessageCount(params);
    }

    @Override
    public YsMessage getMessage(Long studentId, Long id) {
        YsMessage data = courseClassMapper.getMessageById(id,studentId);
        if (data != null && data.getReadingState() == 0){
            courseClassMapper.insertMessageState(id,studentId);
        }
        return data;
    }

}
